#include "app.h"
#include "net.h"
#include "hal_aes.h"

#ifdef MAIN_MODULE
    #include "main_module.h"
#else
    #include "sub_module.h"
#endif // MAIN_MODULE

static uint8_t g_aes_key[16];

void app_init()
{
    memset(g_aes_key, 0xff, sizeof(g_aes_key));

#ifdef MAIN_MODULE
    main_module_init();
#else
    sub_module_init();
#endif // MAIN_MODULE
}

void *app_get_trans_payload()
{
    app_header_t *app = net_get_trans_payload();

    return app->payload;
}

void app_rf_recv_deal(uint8_t *data, uint8_t len, uint8_t *segaddr, uint8_t srcaddr, uint8_t dstaddr, uint8_t rssi)
{
    if(dstaddr != NWK_BROADCAST_ADDR  && srcaddr != NWK_NULL_ADDR)
    {
        app_decrypt(srcaddr, data, len - NWK_END_CONTENT_LEN);
    }

#ifdef MAIN_MODULE
    main_module_recv_deal(data, len, segaddr, srcaddr, dstaddr, rssi);
#else
    sub_module_recv_deal(data, len, segaddr, srcaddr, dstaddr, rssi);
#endif // MAIN_MODULE`
}

uint8_t app_transmit(uint8_t type, uint8_t addr, uint8_t len)
{
    app_header_t *app = net_get_trans_payload();
    app->type = type;
    if(addr != NWK_BROADCAST_ADDR  && net_get_myaddr() != NWK_NULL_ADDR)
    {
        app_encrypt(addr, app, len + sizeof(app_header_t));
    }
    return net_transmit(addr, sizeof(app_header_t) + len);
}
#if 0
uint8_t app_transmit_directly(uint8_t type, uint8_t addr, uint8_t len)
{
    app_header_t *app = net_get_trans_payload();
    app->type = type;

    if(addr != NWK_BROADCAST_ADDR  && net_get_myaddr() != NWK_NULL_ADDR)
    {
        app_encrypt(addr, app, len + sizeof(app_header_t));
    }
    return net_transmit_directly(addr, sizeof(app_header_t) + len);
}
#endif

void app_encrypt(uint8_t addr, void *data, uint8_t len)
{
    uint8_t *tmp_key;
    tmp_key = app_get_key(addr);
    if(tmp_key != NULL)
    {
        memcpy(g_aes_key, tmp_key, NETKEY_LEN);
        //hal_aes_encrypt(data, data, len, g_aes_key);
        AesCTREncrypt(data, data, len, g_aes_key, 16);
    }
}

void app_decrypt(uint8_t addr, void *data, uint8_t len)
{
    uint8_t *tmp_key;
    tmp_key = app_get_key(addr);
    if(tmp_key != NULL)
    {
        memcpy(g_aes_key, tmp_key, NETKEY_LEN);
        AesCTRDecrypt(data, data, len, g_aes_key, 16);
    }
}

uint8_t *app_get_key(uint8_t addr)
{
#ifdef MAIN_MODULE
    return main_module_get_key(addr);
#else
    return sub_module_get_key(addr);
#endif // MAIN_MODULE
}

void app_poll()
{
#ifdef MAIN_MODULE
    main_module_poll();
#else
    sub_module_poll();
#endif // MAIN_MODULE
}

void app_ack_sync_content_cb(uint8_t *data, uint8_t len)
{
#ifdef MAIN_MODULE
    main_module_ack_sync_content_cb(data, len);
#else
    sub_module_ack_sync_content_cb(data, len);
#endif // MAIN_MODULE
}

uint8_t app_ack_sync_content_set(uint8_t *data)
{
#ifdef MAIN_MODULE
    return main_module_ack_sync_content_set(data);
#else
    return sub_module_ack_sync_content_set(data);
#endif // MAIN_MODULE
}
